home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -in_the_mag- / emulation / macos / uae069b2.src.cpt.hqx / UAE069ß2.SRC.CPT / uae069fl2.src / expansion.c < prev    next >
C/C++ Source or Header  |  1997-06-13  |  15KB  |  531 lines

  1.  /* 
  2.   * UAE - The Un*x Amiga Emulator
  3.   * 
  4.   *  Expansion Slots
  5.   *
  6.   * Copyright 1996 Stefan Reinauer <stepan@matrix.kommune.schokola.de>
  7.   */
  8.  
  9. #include "sysconfig.h"
  10. #include "sysdeps.h"
  11.  
  12. #include "config.h"
  13. #include "options.h"
  14. #include "uae.h"
  15. #include "my_memory.h"
  16. #include "custom.h"
  17. #include "readcpu.h"
  18. #include "newcpu.h"
  19. #include "autoconf.h"
  20.  
  21. #define MAX_EXPANSION_BOARDS 5
  22.  
  23. /* 00 / 02 */
  24.  
  25. #define MEM_8MB    0x00        /* Size of Memory Block           */
  26. #define MEM_4MB    0x07
  27. #define MEM_2MB    0x06
  28. #define MEM_1MB    0x05
  29. #define MEM_512KB  0x04
  30. #define MEM_256KB  0x03
  31. #define MEM_128KB  0x02
  32. #define MEM_64KB   0x01
  33.  
  34. #define same_slot  0x08     /* Next card is in the same Slot  */
  35. #define rom_card   0x10     /* Card has valid ROM             */
  36. #define add_memory 0x20     /* Add Memory to List of Free Ram */
  37.  
  38. #define generic    0xc0     /* Type of Expansion Card         */
  39. #define future1    0x00
  40. #define future2    0x40
  41. #define future3    0x80
  42.  
  43. /* ********************************************************** */
  44.  
  45. /* Card Data */
  46.  
  47. /* 04 - 06 & 10-16 */
  48. #define commodore_g   513  /* Commodore Braunschweig (Germany) */
  49. #define commodore     514  /* Commodore West Chester           */
  50. #define gvp         2017  /* GVP */
  51. #define hackers_id   2011
  52.  
  53. #define   commodore_a2091         3  /* A2091 / A590 Card from C=   */
  54. #define   commodore_a2091_ram    10  /* A2091 / A590 Ram on HD-Card */
  55. #define   commodore_a2232        70  /* A2232 Multiport Expansion   */
  56.  
  57. #define   gvp_series_2_scsi      11
  58. #define   gvp_iv_24_gfx          32
  59.  
  60. /* ********************************************************** */
  61. /* 08-0A */
  62.  
  63. #define no_shutup  64  /* Card cannot receive Shut_up_forever */
  64. #define care_addr 128  /* Adress HAS to be $200000-$9fffff    */
  65.  
  66. /* ********************************************************** */
  67.  
  68. /* 40-42 */
  69. #define enable_irq   1  /* enable Interrupt                   */ 
  70. #define reset_card   4  /* Reset of Expansion Card            */
  71. #define card_int2   16  /* READ ONLY: IRQ 2 occured           */
  72. #define card_irq6   32  /* READ ONLY: IRQ 6 occured           */
  73. #define card_irq7   64  /* READ ONLY: IRQ 7 occured           */
  74. #define does_irq   128  /* READ ONLY: Karte loest ger. IRQ aus*/
  75.  
  76. /* ********************************************************** */
  77.  
  78. /* ROM defines */
  79.  
  80. #define rom_4bit    (0x00<<14) /* ROM width */
  81. #define rom_8bit    (0x01<<14)
  82. #define rom_16bit   (0x02<<14)
  83.  
  84. #define rom_never   (0x00<<12) /* Never run Boot Code       */
  85. #define rom_install (0x01<<12) /* run code at install time  */
  86. #define rom_binddrv (0x02<<12) /* run code with binddrivers */
  87.  
  88. uaecptr ROM_filesys_resname = 0, ROM_filesys_resid = 0;
  89. uaecptr ROM_filesys_diagentry = 0;
  90. uaecptr ROM_hardfile_resname = 0, ROM_hardfile_resid = 0;
  91. uaecptr ROM_hardfile_init = 0;
  92.  
  93. /* ********************************************************** */
  94.  
  95. static void expamem_init_clear(void);
  96. static void expamem_map_clear(void);
  97. static void expamem_init_fastcard(void);
  98. static void expamem_map_fastcard(void);
  99. static void expamem_init_filesys(void);
  100. static void expamem_map_filesys(void);
  101.  
  102. void (*card_init[MAX_EXPANSION_BOARDS])(void);
  103. void (*card_map[MAX_EXPANSION_BOARDS])(void);
  104.  
  105. int ecard = 0;
  106.  
  107. /*
  108.  *  Fast Memory
  109.  */
  110.  
  111. static uae_u32 fastmem_mask;
  112.  
  113. static uae_u32 fastmem_lget(uaecptr) REGPARAM;
  114. static uae_u32 fastmem_wget(uaecptr) REGPARAM;
  115. static uae_u32 fastmem_bget(uaecptr) REGPARAM;
  116. static void  fastmem_lput(uaecptr, uae_u32) REGPARAM;
  117. static void  fastmem_wput(uaecptr, uae_u32) REGPARAM;
  118. static void  fastmem_bput(uaecptr, uae_u32) REGPARAM;
  119. static int   fastmem_check(uaecptr addr, uae_u32 size) REGPARAM;
  120. static uae_u8 *fastmem_xlate(uaecptr addr) REGPARAM;
  121.  
  122. static uae_u32 fastmem_start; /* Determined by the OS */
  123. static uae_u8 *fastmemory = NULL;
  124.  
  125. uae_u32 REGPARAM2 fastmem_lget(uaecptr addr)
  126. {
  127.     uae_u8 *m;
  128.     addr -= fastmem_start & fastmem_mask;
  129.     addr &= fastmem_mask;
  130.     m = fastmemory + addr;
  131.     return do_get_mem_long ((uae_u32 *)m);
  132. }
  133.  
  134. uae_u32 REGPARAM2 fastmem_wget(uaecptr addr)
  135. {
  136.     uae_u8 *m;
  137.     addr -= fastmem_start & fastmem_mask;
  138.     addr &= fastmem_mask;
  139.     m = fastmemory + addr;
  140.     return do_get_mem_word ((uae_u16 *)m);
  141. }
  142.  
  143. uae_u32 REGPARAM2 fastmem_bget(uaecptr addr)
  144. {
  145.     addr -= fastmem_start & fastmem_mask;
  146.     addr &= fastmem_mask;
  147.     return fastmemory[addr];
  148. }
  149.  
  150. void REGPARAM2 fastmem_lput(uaecptr addr, uae_u32 l)
  151. {
  152.     uae_u8 *m;
  153.     addr -= fastmem_start & fastmem_mask;
  154.     addr &= fastmem_mask;
  155.     m = fastmemory + addr;
  156.     do_put_mem_long ((uae_u32 *)m, l);
  157. }
  158.  
  159. void REGPARAM2 fastmem_wput(uaecptr addr, uae_u32 w)
  160. {
  161.     uae_u8 *m;
  162.     addr -= fastmem_start & fastmem_mask;
  163.     addr &= fastmem_mask;
  164.     m = fastmemory + addr;
  165.     do_put_mem_word ((uae_u16 *)m, w);
  166. }
  167.  
  168. void REGPARAM2 fastmem_bput(uaecptr addr, uae_u32 b)
  169. {
  170.     addr -= fastmem_start & fastmem_mask;
  171.     addr &= fastmem_mask;
  172.     fastmemory[addr] = b;
  173. }
  174.  
  175. static int REGPARAM2 fastmem_check(uaecptr addr, uae_u32 size)
  176. {
  177.     addr -= fastmem_start & fastmem_mask;
  178.     addr &= fastmem_mask;
  179.     return (addr + size) < fastmem_size;
  180. }
  181.  
  182. static uae_u8 REGPARAM2 *fastmem_xlate(uaecptr addr)
  183. {
  184.     addr -= fastmem_start & fastmem_mask;
  185.     addr &= fastmem_mask;
  186.     return fastmemory + addr;
  187. }
  188.  
  189. addrbank fastmem_bank = {
  190.     fastmem_lget, fastmem_wget, fastmem_bget,
  191.     fastmem_lput, fastmem_wput, fastmem_bput,
  192.     fastmem_xlate, fastmem_check
  193. };
  194.  
  195.  
  196. /*
  197.  * Filesystem device ROM
  198.  * This is very simple, the Amiga shouldn't be doing things with it. 
  199.  */
  200.  
  201. static uae_u32 filesys_lget(uaecptr) REGPARAM;
  202. static uae_u32 filesys_wget(uaecptr) REGPARAM;
  203. static uae_u32 filesys_bget(uaecptr) REGPARAM;
  204. static void  filesys_lput(uaecptr, uae_u32) REGPARAM;
  205. static void  filesys_wput(uaecptr, uae_u32) REGPARAM;
  206. static void  filesys_bput(uaecptr, uae_u32) REGPARAM;
  207.  
  208. static uae_u32 filesys_start; /* Determined by the OS */
  209. uae_u8 filesysory[65536];
  210.  
  211. uae_u32 REGPARAM2 filesys_lget(uaecptr addr)
  212. {
  213.     uae_u8 *m;
  214.     addr -= filesys_start & 65535;
  215.     addr &= 65535;
  216.     m = filesysory + addr;
  217.     return do_get_mem_long ((uae_u32 *)m);
  218. }
  219.  
  220. uae_u32 REGPARAM2 filesys_wget(uaecptr addr)
  221. {
  222.     uae_u8 *m;
  223.     addr -= filesys_start & 65535;
  224.     addr &= 65535;
  225.     m = filesysory + addr;
  226.     return do_get_mem_word ((uae_u16 *)m);
  227. }
  228.  
  229. uae_u32 REGPARAM2 filesys_bget(uaecptr addr)
  230. {
  231.     addr -= filesys_start & 65535;
  232.     addr &= 65535;
  233.     return filesysory[addr];
  234. }
  235.  
  236. static void REGPARAM2 filesys_lput(uaecptr addr, uae_u32 l)
  237. {
  238.     write_log ("filesys_lput called\n");
  239. }
  240.  
  241. static void REGPARAM2 filesys_wput(uaecptr addr, uae_u32 w)
  242. {
  243.     write_log ("filesys_wput called\n");
  244. }
  245.  
  246. static void REGPARAM2 filesys_bput(uaecptr addr, uae_u32 b)
  247. {
  248.     fprintf (stderr, "filesys_bput called. This usually means that you are using\n");
  249.     fprintf (stderr, "Kickstart 1.2. Please give UAE the \"-a\" option next time\n");
  250.     fprintf (stderr, "you start it. If you are _not_ using Kickstart 1.2, then\n");
  251.     fprintf (stderr, "there's a bug somewhere.\n");
  252.     fprintf (stderr, "Exiting...\n");
  253.     uae_quit ();
  254. }
  255.  
  256. addrbank filesys_bank = {
  257.     filesys_lget, filesys_wget, filesys_bget,
  258.     filesys_lput, filesys_wput, filesys_bput,
  259.     default_xlate, default_check
  260. };
  261.  
  262. /* Autoconfig address space at 0xE80000 */
  263. static uae_u8 expamem[65536];
  264.  
  265. static uae_u8 expamem_lo;
  266. static uae_u8 expamem_hi;
  267.  
  268. static uae_u32 expamem_lget(uaecptr) REGPARAM;
  269. static uae_u32 expamem_wget(uaecptr) REGPARAM;
  270. static uae_u32 expamem_bget(uaecptr) REGPARAM;
  271. static void  expamem_lput(uaecptr, uae_u32) REGPARAM;
  272. static void  expamem_wput(uaecptr, uae_u32) REGPARAM;
  273. static void  expamem_bput(uaecptr, uae_u32) REGPARAM;
  274.  
  275. addrbank expamem_bank = {
  276.     expamem_lget, expamem_wget, expamem_bget,
  277.     expamem_lput, expamem_wput, expamem_bput,
  278.     default_xlate, default_check
  279. };
  280.  
  281. static uae_u32 REGPARAM2 expamem_lget(uaecptr addr)
  282. {
  283.     sprintf (warning_buffer, "warning: READ.L from address $%lx \n", addr);
  284.     write_log (warning_buffer);
  285.     return 0xfffffffful;
  286. }
  287.  
  288. static uae_u32 REGPARAM2 expamem_wget(uaecptr addr)
  289. {
  290.     sprintf (warning_buffer, "warning: READ.W from address $%lx \n", addr);
  291.     write_log (warning_buffer);
  292.     return 0xffff;
  293. }
  294.  
  295. static uae_u32 REGPARAM2 expamem_bget(uaecptr addr)
  296. {
  297.     uae_u8 value;
  298.     addr &= 0xFFFF;
  299.     return expamem[addr];
  300. }
  301.  
  302. static void  REGPARAM2 expamem_write(uaecptr addr, uae_u32 value)
  303. {
  304.     addr &= 0xffff;
  305.     if (addr==00 || addr==02 || addr==0x40 || addr==0x42) {
  306.     expamem[addr] = (value & 0xf0);
  307.     expamem[addr+2] = (value & 0x0f) << 4;
  308.     } else {
  309.     expamem[addr] = ~(value & 0xf0);
  310.     expamem[addr+2] = ~((value & 0x0f) << 4);
  311.     }
  312. }
  313.  
  314. static void REGPARAM2 expamem_lput(uaecptr addr, uae_u32 value)
  315. {
  316.     fprintf(stderr,"warning: WRITE.L to address $%lx : value $%lx\n",addr,value);
  317. }
  318.  
  319. static void REGPARAM2 expamem_wput(uaecptr addr, uae_u32 value)
  320. {
  321.     fprintf(stderr,"warning: WRITE.W to address $%lx : value $%x\n",addr,value);
  322. }
  323.  
  324. static void REGPARAM2 expamem_bput(uaecptr addr, uae_u32 value)
  325. {
  326.     static char buffer[80];
  327.     switch (addr&0xff) {
  328.      case 0x30:
  329.      case 0x32:
  330.     expamem_hi = 0;
  331.     expamem_lo = 0;
  332.     expamem_write (0x48, 0x00);
  333.     break;
  334.  
  335.      case 0x48:
  336.     expamem_hi = value;
  337.         (*card_map[ecard])();
  338.         sprintf (buffer, "   Card %d done.\n",ecard+1);
  339.     write_log (buffer);
  340.         ++ecard;
  341.         if (ecard <= MAX_EXPANSION_BOARDS)
  342.         (*card_init[ecard])();
  343.     else
  344.         expamem_init_clear();
  345.            break;
  346.     
  347.      case 0x4a:    
  348.     expamem_lo = value;
  349.     break;
  350.     
  351.      case 0x4c:
  352.         sprintf (buffer,"   Card %d had no success.\n",ecard+1);
  353.     write_log (buffer);
  354.         ++ecard;
  355.         if (ecard <= MAX_EXPANSION_BOARDS) 
  356.         (*card_init[ecard])();
  357.     else  
  358.         expamem_init_clear();
  359.         break;
  360.     }
  361. }
  362.  
  363. void expamem_reset()
  364. {
  365.     int cardno = 0;
  366.  
  367.     ecard = 0;
  368.     
  369.     if (fastmemory != NULL) {
  370.     card_init[cardno] = expamem_init_fastcard;
  371.     card_map[cardno++] = expamem_map_fastcard;
  372.     }
  373.  
  374.     if (currprefs.automount_uaedev && !ersatzkickfile) {
  375.     card_init[cardno] = expamem_init_filesys;
  376.     card_map[cardno++] = expamem_map_filesys;
  377.     }
  378.  
  379.     while (cardno < MAX_EXPANSION_BOARDS) {
  380.     card_init[cardno] = expamem_init_clear;
  381.     card_map[cardno++] = expamem_map_clear;
  382.     }
  383.     
  384.     (*card_init[0])();
  385. }
  386.  
  387. void expansion_init(void)
  388. {
  389.     if (fastmem_size > 0) {
  390.     fastmem_mask = fastmem_size - 1;
  391.     fastmemory = (uae_u8 *)calloc(fastmem_size,1);
  392.     if (fastmemory == NULL) {
  393.         write_log ("Out of memory for fastmem card.\n");
  394.     }
  395.     }
  396. }
  397.  
  398. /*
  399.  *     Expansion Card (ZORRO II) for 1/2/4/8 MB of Fast Memory
  400.  */
  401.  
  402. void expamem_map_fastcard()
  403. {
  404.     char buffer[80];
  405.     fastmem_start = ((expamem_hi|(expamem_lo>>4)) << 16);
  406.     map_banks (&fastmem_bank, fastmem_start >> 16, fastmem_size >> 16);
  407.     sprintf (buffer, "Fastcard: mapped @$%lx: %dMB fast memory\n",fastmem_start, fastmem_size >>20);
  408.     write_log (buffer);
  409. }
  410.  
  411. void expamem_init_fastcard()
  412. {
  413.     expamem_init_clear();
  414.     if (fastmem_size==0x100000)
  415.     expamem_write (0x00, MEM_1MB+add_memory+generic);
  416.     else if (fastmem_size==0x200000)
  417.     expamem_write (0x00, MEM_2MB+add_memory+generic);
  418.     else if (fastmem_size==0x400000)
  419.     expamem_write (0x00, MEM_4MB+add_memory+generic);
  420.     else if (fastmem_size==0x800000)
  421.     expamem_write (0x00, MEM_8MB+add_memory+generic);
  422.  
  423.     expamem_write (0x08, care_addr);
  424.  
  425.     expamem_write (0x04, 1);
  426.     expamem_write (0x10, hackers_id >> 8);
  427.     expamem_write (0x14, hackers_id & 0x0f);
  428.  
  429.     expamem_write (0x18, 0x00); /* ser.no. Byte 0 */
  430.     expamem_write (0x1c, 0x00); /* ser.no. Byte 1 */
  431.     expamem_write (0x20, 0x00); /* ser.no. Byte 2 */
  432.     expamem_write (0x24, 0x01); /* ser.no. Byte 3 */
  433.  
  434.     expamem_write (0x28, 0x00); /* Rom-Offset hi  */
  435.     expamem_write (0x2c, 0x00); /* ROM-Offset lo  */
  436.  
  437.     expamem_write (0x40, 0x00); /* Ctrl/Statusreg.*/
  438. }
  439.  
  440. /* 
  441.  * Filesystem device
  442.  */
  443.  
  444. void expamem_map_filesys()
  445. {
  446.     uaecptr a;
  447.     
  448.     filesys_start = ((expamem_hi | (expamem_lo >> 4)) << 16);
  449.     map_banks(&filesys_bank, filesys_start >> 16, 1);
  450.     /* 68k code needs to know this. */
  451.     a = here ();
  452.     org (0xF0FFFC);
  453.     dl (filesys_start + 0x2000);
  454.     org (a);
  455. }
  456.  
  457. void expamem_init_filesys()
  458. {
  459.     uae_u8 diagarea[] = { 0x90, 0x00, 0x01, 0x0C, 0x01, 0x00, 0x01, 0x06 };
  460.  
  461.     expamem_init_clear();
  462.     expamem_write (0x00, MEM_64KB | rom_card | generic);
  463.  
  464.     expamem_write (0x08, care_addr | no_shutup);
  465.  
  466.     expamem_write (0x04, 2);
  467.     expamem_write (0x10, hackers_id >> 8);
  468.     expamem_write (0x14, hackers_id & 0x0f);
  469.  
  470.     expamem_write (0x18, 0x00); /* ser.no. Byte 0 */
  471.     expamem_write (0x1c, 0x00); /* ser.no. Byte 1 */
  472.     expamem_write (0x20, 0x00); /* ser.no. Byte 2 */
  473.     expamem_write (0x24, 0x01); /* ser.no. Byte 3 */
  474.  
  475.     expamem_write (0x28, 0x10); /* Rom-Offset hi  */
  476.     expamem_write (0x2c, 0x00); /* ROM-Offset lo  */
  477.  
  478.     expamem_write (0x40, 0x00); /* Ctrl/Statusreg.*/
  479.  
  480.     /* Build a DiagArea */
  481.     memcpy(expamem + 0x1000, diagarea, sizeof diagarea);
  482.     
  483.     /* Call DiagEntry */
  484.     do_put_mem_word ((uae_u16 *)(expamem + 0x1100), 0x4EF9); /* JMP */
  485.     do_put_mem_long ((uae_u32 *)(expamem + 0x1102), ROM_filesys_diagentry);
  486.  
  487.     /* What comes next is a plain bootblock */
  488.     do_put_mem_word ((uae_u16 *)(expamem + 0x1106), 0x4EF9); /* JMP */
  489.     do_put_mem_long ((uae_u32 *)(expamem + 0x1108), EXPANSION_bootcode);
  490.     
  491.     /* Build a DOS param packet template */
  492.     do_put_mem_long ((uae_u32 *)(expamem + 0x2000 + 12), 0); /* Device flags */
  493.     do_put_mem_long ((uae_u32 *)(expamem + 0x2000 + 16), 16); /* Env. size */
  494.     do_put_mem_long ((uae_u32 *)(expamem + 0x2000 + 20), 128); /* 512 bytes/block */
  495.     do_put_mem_long ((uae_u32 *)(expamem + 0x2000 + 24), 0); /* unused */
  496.     do_put_mem_long ((uae_u32 *)(expamem + 0x2000 + 28), 1); /* heads */
  497.     do_put_mem_long ((uae_u32 *)(expamem + 0x2000 + 32), 1); /* unused */
  498.     do_put_mem_long ((uae_u32 *)(expamem + 0x2000 + 36), 32); /* secs per track */
  499.     do_put_mem_long ((uae_u32 *)(expamem + 0x2000 + 40), 1); /* reserved blocks */
  500.     do_put_mem_long ((uae_u32 *)(expamem + 0x2000 + 44), 0); /* unused */
  501.     do_put_mem_long ((uae_u32 *)(expamem + 0x2000 + 48), 0); /* interleave */
  502.     do_put_mem_long ((uae_u32 *)(expamem + 0x2000 + 52), 0); /* lowCyl */
  503.     {
  504.     extern int numtracks;
  505.     do_put_mem_long ((uae_u32 *)(expamem + 0x2000 + 56), numtracks-1); /* upperCyl */
  506.     }
  507.     do_put_mem_long ((uae_u32 *)(expamem + 0x2000 + 60), 0); /* Number of buffers */
  508.     do_put_mem_long ((uae_u32 *)(expamem + 0x2000 + 64), 0); /* Buffer mem type */
  509.     do_put_mem_long ((uae_u32 *)(expamem + 0x2000 + 68), 0x7FFFFFFF); /* largest transfer */
  510.     do_put_mem_long ((uae_u32 *)(expamem + 0x2000 + 72), ~1); /* addMask (?) */
  511.     do_put_mem_long ((uae_u32 *)(expamem + 0x2000 + 76), (uae_u32)-1); /* bootPri */
  512.     do_put_mem_long ((uae_u32 *)(expamem + 0x2000 + 80), 0x444f5300); /* DOS\0 */
  513.     do_put_mem_long ((uae_u32 *)(expamem + 0x2000 + 84), 0); /* pad */
  514.     
  515.     memcpy(filesysory, expamem, 0x3000);
  516. }
  517.  
  518. /*
  519.  *  Dummy Entries to show that there's no card in a slot
  520.  */
  521.  
  522. void expamem_map_clear()
  523. {
  524.     fprintf(stderr, "expamem_map_clear() got called. Shouldn't happen.\n");
  525. }
  526.  
  527. void expamem_init_clear()
  528. {
  529.     memset (expamem,0xff,sizeof expamem);
  530. }
  531.